package juc;

import java.io.IOException;
/*
public final void wait()
                throws InterruptedException导致当前线程等待，直到另一个线程调用该对象的notify()方法或notifyAll()方法。 换句话说，这个方法的行为就好像简单地执行呼叫wait(0) 。
当前的线程必须拥有该对象的显示器。 该线程释放此监视器的所有权，并等待另一个线程通知等待该对象监视器的线程通过调用notify方法或notifyAll方法notifyAll 。 然后线程等待，直到它可以重新获得监视器的所有权并恢复执行。

像在一个参数版本中，中断和虚假唤醒是可能的，并且该方法应该始终在循环中使用：

  synchronized (obj) {
         while (<condition does not hold>)
             obj.wait();
         ... // Perform action appropriate to condition
     } 该方法只能由作为该对象的监视器的所有者的线程调用。 有关线程可以成为监视器所有者的方式的说明，请参阅notify方法。

 */
public class Test09 {
    public static void main(String[] args) {
        //资源类对象
        AirCondition airCondition = new AirCondition();

        new Thread(() -> {
            for (int i = 1; i <=20; i++) {
                try {
                    Thread.sleep(300);
                    airCondition.increment();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        },"A").start();
        new Thread(() -> {
            for (int i = 1; i <=20 ; i++) {
                try {
                    Thread.sleep(200);
                    airCondition.decrement();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        },"B").start();
        new Thread(() -> {
            for (int i = 1; i <=20; i++) {
                try {
                    Thread.sleep(400);
                    airCondition.increment();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        },"C").start();
        new Thread(() -> {
            for (int i = 1; i <=20 ; i++) {
                try {
                    Thread.sleep(500);
                    airCondition.decrement();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        },"D").start();

    }
}
class AirCondition {
    private int num = 0;

    public synchronized void increment() throws Exception {
        while (num != 0)
        /*if(num != 0)*/
        {
            this.wait();
        }
        num++;
        System.out.println(Thread.currentThread().getName() +"\t" + num);

        this.notifyAll();
    }

    public synchronized void decrement() throws Exception {
        while (num == 0)
        /*if(num == 0)*/
        {
            this.wait();
        }
        num--;
        System.out.println(Thread.currentThread().getName() + "\t" + num);

        this.notifyAll();
    }
}